/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.web.application;

import com.jb.util.Meter;
import com.jb.web.bean.Page;
import com.jb.web.context.WebContext;

import java.io.IOException;

import java.util.Locale;

import com.jb.faces.FacesException;
import com.jb.faces.application.ViewHandler;
import com.jb.faces.component.UIViewRoot;
import com.jb.faces.context.FacesContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Implementation of JSF ViewHandler
 */
public class ViewHandlerImpl extends ViewHandler {
    static private Log log = LogFactory.getLog(ViewHandlerImpl.class.getName());
    

    public ViewHandlerImpl() {
        super();
    }

    public String getActionURL(FacesContext context, String viewId) {
        return viewId + "xsp";
    }

    public String getResourceURL(FacesContext context, String viewId) {
        return viewId + "xsp";
    }

    public Locale calculateLocale(FacesContext context) {
        return Locale.getDefault();
    }

    public String calculateRenderKitId(FacesContext context) {
        return "not_implemented";
    }

    public UIViewRoot createView(FacesContext context, String viewId) {
        UIViewRoot view = context.getViewRoot();

        if (view == null) {
            view = new UIViewRoot();
        }

        view.setId(viewId);
        view.setLocale(calculateLocale(context));
        view.setRenderKitId(calculateRenderKitId(context));

        return view;
    }

    //Renderering the result to the writer
    public void renderView(FacesContext context, UIViewRoot view)
        throws java.io.IOException, FacesException {
        // long l = System.currentTimeMillis();
        WebContext webContext = (WebContext) context;
        Page respondRegion = (Page) webContext.getRespondTree();

        if ((respondRegion != null) && webContext.isError()) {
            if ((respondRegion.getErrorPage() != null) && (respondRegion.getErrorPage().length() != 0)) {
                webContext.setRespondPage(respondRegion.getErrorPage());
                respondRegion = (Page) webContext.getRespondTree();
            }
        }

        StringBuffer respondString = new StringBuffer();
        Page toolBar = (Page) webContext.getToolBar();

        if (!webContext.isRunTime() && (toolBar != null) && "true".equalsIgnoreCase(toolBar.getVisible())) {
            toolBar.updateView(webContext);
        }

        if (respondRegion != null) {
            Meter.start();
            respondRegion.updateView(webContext);
            Meter.stop("updateView");

            if ((webContext.getRedirectPage() != null)) {
                try {
                    webContext.getResponse().sendRedirect(webContext.getRedirectPage());
                    webContext.isResponseComplete = true;

                    return;
                } catch (IOException e) {
                    if (log.isFatalEnabled()) {
                        log.fatal(this, e);
                    }
                }
            } else {
                //respondRegion.loadPersonalization(webContext);
                respondString.append(respondRegion.render(webContext));
            }
        } else {
            respondString.append("<font color=\"red\" >Can not render this page</font>");
        }

        context.getResponseWriter().write(respondString.toString());
    }

    public UIViewRoot restoreView(FacesContext context, java.lang.String viewId) {
        UIViewRoot root = createView(context, viewId);
        restoreViewInternal((WebContext) context, root);

        return root;
    }

    public void writeState(FacesContext context) throws java.io.IOException {
        UIViewRoot view = context.getViewRoot();
        view.saveState(context);
    }

    private void restoreViewInternal(WebContext pCtx, UIViewRoot root) {
        if (pCtx.getRespondTree() != null) {
            root.getChildren().add(pCtx.getRespondTree());
            pCtx.getRespondTree().onRestored(pCtx);
        }

        if (pCtx.getToolBar() != null) {
            root.getChildren().add(pCtx.getToolBar());
            pCtx.getToolBar().onRestored(pCtx);
        } else {
        }

        if ((pCtx.getRequestTree() != null) && (pCtx.getRequestTree() != pCtx.getToolBar()) &&
                (pCtx.getRequestTree() != pCtx.getRespondTree())) {
            root.getChildren().add(pCtx.getRequestTree());
            pCtx.getRequestTree().onRestored(pCtx);
        }
    }
}
